package com.smartfast4j.redis;

import org.apache.log4j.Logger;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

import java.io.*;
import java.util.HashSet;
import java.util.ResourceBundle;
import java.util.Set;

/***
 * Jedis集群客户端实现
 */
public class JedisClientCluster implements JedisClient {

	private static Logger logger = Logger.getLogger(JedisClientCluster.class);

	private static JedisCluster jedisCluster;

	/**
	 * 获取实例
	 *
	 * @return
	 */
	public static JedisClientCluster getInstance() {
		return new JedisClientCluster();
	}


	static {
		//读取相关的配置
		ResourceBundle resourceBundle = ResourceBundle.getBundle("redis");
		//获取Redis集群节点配置
		String redisClusterNodes = resourceBundle.getString("redis.cluster");
		//logger.info("Redis集群节："+redisClusterNodes);
		String[] redisClusterNodeArr = redisClusterNodes.split(",");//按逗号分隔
		//logger.info("Redis集群节点数量："+redisClusterNodeArr.length);
		/**
		 * Redis集群节点配置
		 */
		Set<HostAndPort> jedisClusterNodes = new HashSet<>();
		for(String redisNode:redisClusterNodeArr){
			String ip = redisNode.split(":")[0];//Redis节点IP地址
			Integer port =Integer.parseInt(redisNode.split(":")[1]);//Redis节点端口号
			//logger.info("Redis集群节点，IP="+ip+"，端口号="+port);
			jedisClusterNodes.add(new HostAndPort(ip,port));
		}
		//jc = new JedisCluster(jedisClusterNodes);
		//解决redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirections?
		//JedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections) ;
		jedisCluster = new JedisCluster(jedisClusterNodes,5000,1000);//初始化JedisCluster时，设定JedisCluster的maxRedirections
	}

	@Override
	public String get(String key) {
		return jedisCluster.get(key);
	}

	@Override
	public String set(String key, String value) {
		return jedisCluster.set(key, value);
	}

	@Override
	public String hget(String hkey, String key) {
		return jedisCluster.hget(hkey, key);
	}

	@Override
	public long hset(String hkey, String key, String value) {
		return jedisCluster.hset(hkey, key, value);
	}

	@Override
	public long incr(String key) {
		return jedisCluster.incr(key);
	}

	@Override
	public long expire(String key, int second) {
		return jedisCluster.expire(key, second);
	}

	@Override
	public long ttl(String key) {
		return jedisCluster.ttl(key);
	}

	@Override
	public long del(String key) {
		
		return jedisCluster.del(key);
	}

	@Override
	public long hdel(String hkey, String key) {
		
		return jedisCluster.hdel(hkey, key);
	}

	@Override
	// 保存byte类型数据
	public  void setObject(byte[] key, byte[] value){
		jedisCluster.set(key,value);
	}

	@Override
	// 获取byte类型数据
	public  byte[] getObject(byte[] key){
		return jedisCluster.get(key);
	}

	@Override
	public long del(byte[] key) {
		return jedisCluster.del(key);
	}

	@Override
	public <T> void setObject(String key, T obj) {
		setObject(key.getBytes(),objectToByte(obj));
	}

	@Override
	public <T> T getObject(String key, Class<T> clazz) {
		return byteToObject(getObject(key.getBytes()),clazz);
	}

	/**
	 * 把byte还原为Object
	 * @param bytes
	 * @param clazz
	 * @param <T>
	 * @return
	 */
	private <T> T byteToObject(byte[] bytes,Class<T> clazz){
		ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
		ObjectInputStream in;
		T t = null;
		try {
			in = new ObjectInputStream(bi);
			t = (T) in.readObject();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return t;
	}

	/**
	 * 把对象转化为byte
	 * @param object
	 * @return
	 */
	private byte[] objectToByte(Object object){
		ByteArrayOutputStream bo = new ByteArrayOutputStream();
		byte[] bytes = null;
		try {
			ObjectOutputStream oo = new ObjectOutputStream(bo);
			oo.writeObject(object);
			bytes = bo.toByteArray();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bytes;
	}

	public static JedisCluster getJedisCluster() {
		return jedisCluster;
	}
}
